package com.koron.common.core.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.koron.bean.base.Response;
import com.koron.bean.system.role.AppOrgJurisdictionBean;
import com.koron.bean.system.role.UserOwnJurisdictionBean;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.business.configsettings.utils.ConfigInfoTool;
import com.koron.common.core.config.ThreadLocalContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author twcao
 * @title: CommonUtils
 * @projectName GDH_EAM_V2
 * @description: 共用工具类
 * @date 2021/9/116:37
 */
@Slf4j
public class CommonUtils {

    /**
     * 语言分割符
     */
    public static final String LANGUAGE_SPLIT = "###";

    /**
     * cron表达式的分隔符
     */
    public static final String CRON_SPLIT = " ";

    /***
     * convert Date to cron, eg "0 07 10 15 1 ? 2016"
     * @param date  : 时间点
     * @return
     */
    public static String getCron(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
        String formatTimeStr = null;
        if (Objects.nonNull(date)) {
            formatTimeStr = sdf.format(date);
        }
        return formatTimeStr;
    }

    /**
     * 获取集合重复的元素
     * @param list
     * @param <E>
     * @return
     */
    public static <E> List<E> getDuplicateElements(List<E> list) {
        return list.stream() // list 对应的 Stream
                .collect(Collectors.toMap(e -> e, e -> 1, (a, b) -> a + b)) // 获得元素出现频率的 Map，键为元素，值为元素出现的次数
                .entrySet().stream() // 所有 entry 对应的 Stream
                .filter(entry -> entry.getValue() > 1) // 过滤出元素出现次数大于 1 的 entry
                .map(Map.Entry::getKey) // 获得 entry 的键（重复元素）对应的 Stream
                .collect(Collectors.toList());  // 转化为 List
    }

    /**
     * 将字符串转为数字
     * @param numStr
     * @return
     */
    public static Integer parse(String numStr) {
        try {
            return Integer.parseInt(numStr);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 是否是正整数
     * @param num
     * @return
     */
    public static boolean isPositive(Integer num) {
        return num != null && num > 0;
    }

    /**
     * 是否是正数
     * @param num
     * @return
     */
    public static boolean isPositive(Double num) {
        return num != null && num > 0;
    }

    /**
     * 获取编码
     * @param prefix 前缀
     * @param length 流水号长度
     * @return 最新的编码
     */
    public static String getCodeNo(String prefix, Integer length) {
        EamUser currentUser = ThreadLocalContext.get();
        String orgName = currentUser.getPrefix();
        Assert.hasText(orgName, "组织编码前缀不能为空");
        // 转成大写
        orgName = StringUtils.upperCase(orgName);
        return CodeTools.getCodeNo(prefix + orgName, length);
    }

    public static <T> T getObject(boolean expression, String msg, Response<T> resp) {
        Assert.isTrue(expression, msg);
        return resp.getData();
    }

    public static <T> T ok(Response<T> resp) {
        return getObject(resp != null && resp.getCode() == 200, resp == null ? "远程调用失败" : resp.getDescription(), resp);
    }

    /**
     * 获取用户组织权限
     * @return
     */
    public static List<String> getPower(EamUser user) {
        ArrayList<String> units = CollUtil.newArrayList(user.getDeptId());
        List<AppOrgJurisdictionBean> appOrgJurisdictionBeans = Optional.ofNullable(user)
                .map(EamUser::getUserOwnJurisdictionBean)
                .map(UserOwnJurisdictionBean::getAppOrgJurisdictionBeanList).orElse(new ArrayList<>());
        Optional<AppOrgJurisdictionBean> firstopt = appOrgJurisdictionBeans.stream().filter(j -> user.getAppId().equals(j.getAppId())).findFirst();
        if (firstopt.isPresent()) {
            units.addAll(firstopt.get().getOrgStrList());
        }
        return units;
    }

    /**
     * 获取配置
     * @param propertyStr   配置路径
     * @return
     */
    public static String getProperty(String propertyStr){
        return  SpringUtils.getApplicationContext().getEnvironment().getProperty(propertyStr);
    }

    /**
     * 获取当前语言
     * @return
     */
    public static Integer getCurrentLanguage() {
        int language = 0;
        Map<String, String> map = ConfigInfoTool.getConfigByCode("common", "language_config");
        if (ObjectUtil.isNotNull(map.get(ThreadLocalContext.get().getLanguage()))) {
            language = Integer.valueOf(map.get(ThreadLocalContext.get().getLanguage()));
        }
        return language;
    }

    /**
     * 根据当前语言转换返回信息
     *
     * @param msg 返回信息    例如：异常简体###error###異常
     * @return
     */
    public static String converMsgByLanguage(String msg) {
        if (StrUtil.contains(msg, LANGUAGE_SPLIT)) {
            List<String> split = StrUtil.split(msg, LANGUAGE_SPLIT);
            if (split.size() == 3) {
                Integer currentLanguage = getCurrentLanguage(); //获取当前语种
                return split.get(currentLanguage);
            }
        }
        return msg;
    }

    /**
     * 格式化多语言
     * @param zhCn 简体  0
     * @param zhHk 繁体  1
     * @param en    英文  2
     * @return
     */
    public static String msgFormat(String zhCn, String zhHk, String en) {
        return StrUtil.join("###", zhCn, zhHk, en);
    }

    /**
     * 英文参数转驼峰参数
     * @param str   引文参数形参
     * @return
     * Equipment Management unit => equipmentManagementUnit
     */
    public static String englishtoCamelCase(String str) {
        String s = StrUtil.toUnderlineCase(str);    // ABC => abc
        String r = StrUtil.replace(s, " ", "_");    // equipment_management_unit => equipmentManagementUnit
        return StrUtil.toCamelCase(r);
    }
}
